<?php

namespace app\admin\model\scanwork;

use think\Model;
use app\admin\model\scanwork\Config as ConfigModel;

/**
 * 溯源码模型
 */
class TraceCode extends Model
{
    // 表名
    protected $name = 'scanwork_trace_codes';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    
    // 字段类型转换
    protected $type = [
        'audit_time' => 'integer',
        'createtime' => 'integer',
        'updatetime' => 'integer',
        'status' => 'integer'
    ];
    
    // 追加属性
    protected $append = [
        'status_text'
    ];
    
    // 状态映射
    public static $statusList = [
        0 => '禁用',
        1 => '正常'
    ];
    
    public function getStatusTextAttr($value, $data)
    {
        return self::$statusList[$data['status']] ?? '未知';
    }
    
    /**
     * 关联报工记录
     */
    public function report()
    {
        return $this->belongsTo('Report', 'report_id', 'id');
    }
    
    /**
     * 生成溯源码
     */
    public static function generateTraceCode($reportId)
    {
        $prefix = 'TR';
        $date = date('Ymd');
        $time = date('His');
        $random = strtoupper(substr(md5(uniqid()), 0, 4));
        
        $traceCode = $prefix . $date . $time . $random;
        
        // 检查是否已存在
        while (self::where('trace_code', $traceCode)->find()) {
            $random = strtoupper(substr(md5(uniqid()), 0, 4));
            $traceCode = $prefix . $date . $time . $random;
        }
        
        return $traceCode;
    }
    
    /**
     * 创建溯源码记录
     */
    public static function createTraceCode($reportId, $additionalData = [])
    {
        $traceCode = self::generateTraceCode($reportId);
        
        $data = [
            'trace_code' => $traceCode,
            'report_id' => $reportId,
            'status' => 1, // 正常
            'createtime' => time(),
            'updatetime' => time()
        ];
        
        // 合并额外数据
        if (!empty($additionalData)) {
            $data = array_merge($data, $additionalData);
        }
        
        return self::create($data);
    }
    
    /**
     * 生成溯源码二维码图片
     */
    public static function generateQrCodeImage($traceCode, $returnUrl = true)
    {
        try {
            $dateDir = date('Ymd');
            $qrDir = ROOT_PATH . 'public' . DS . 'uploads' . DS . 'trace_qrcode' . DS . $dateDir;
            if (!is_dir($qrDir)) {
                mkdir($qrDir, 0755, true);
            }
            
            $filename = "trace_{$traceCode}_" . time() . ".png";
            $filepath = $qrDir . DS . $filename;
            
            // 使用endroid/qr-code库生成二维码
            $qrCode = \Endroid\QrCode\QrCode::create(ConfigModel::getSiteDomain() . '/trace.html?id=' . $traceCode)
                ->setEncoding(new \Endroid\QrCode\Encoding\Encoding('UTF-8'))
                ->setErrorCorrectionLevel(\Endroid\QrCode\ErrorCorrectionLevel::Low)
                ->setSize(300)
                ->setMargin(10)
                ->setRoundBlockSizeMode(\Endroid\QrCode\RoundBlockSizeMode::Margin)
                ->setForegroundColor(new \Endroid\QrCode\Color\Color(0, 0, 0))
                ->setBackgroundColor(new \Endroid\QrCode\Color\Color(255, 255, 255));
            
            $writer = new \Endroid\QrCode\Writer\PngWriter();
            $result = $writer->write($qrCode);
            
            file_put_contents($filepath, $result->getString());
            
            return $returnUrl ? '/uploads/trace_qrcode/' . $dateDir . '/' . $filename : $filepath;
        } catch (\Exception $e) {
            \think\Log::error("溯源码二维码生成失败: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * 根据溯源码获取信息
     */
    public static function getTraceInfo($traceCode)
    {
        $trace = self::where('trace_code', $traceCode)
                    ->where('status', 1)
                    ->find();
        
        if (!$trace) {
            return null;
        }
        
        return $trace->toArray();
    }
    
    /**
     * 根据报工ID获取追溯信息
     */
    public static function getTraceByReportId($reportId)
    {
        $trace = self::where('report_id', $reportId)
                    ->where('status', 1)
                    ->find();
        
        if (!$trace) {
            return null;
        }
        
        return $trace->toArray();
    }
}
